package api

import (
	"net/http"
	"strconv"

	"GinAdmin/core/logger"
	"GinAdmin/model"
	"GinAdmin/service"

	"github.com/gin-gonic/gin"
)

// MenuAPI 菜单API控制器
type MenuAPI struct {
	menuService *service.MenuService
}

// NewMenuAPI 创建菜单API控制器
func NewMenuAPI() *MenuAPI {
	return &MenuAPI{
		menuService: service.NewMenuService(),
	}
}

// GetMenuList 获取菜单列表
// @Summary 获取菜单列表
// @Description 获取菜单列表
// @Tags 菜单管理
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param title query string false "菜单标题"
// @Param path query string false "路由路径"
// @Param status query int false "状态(1:启用,2:禁用)"
// @Param type query int false "菜单类型(0:目录,1:菜单,2:按钮)"
// @Success 200 {object} model.Response "成功"
// @Router /api/menus [get]
func (a *MenuAPI) GetMenuList(c *gin.Context) {
	params := &model.MenuSearchParams{
		Title:  c.Query("title"),
		Path:   c.Query("path"),
		Status: 0,
		Type:   0,
	}

	if status, err := strconv.Atoi(c.DefaultQuery("status", "0")); err == nil {
		params.Status = status
	}

	if typ, err := strconv.Atoi(c.DefaultQuery("type", "0")); err == nil {
		params.Type = typ
	}

	menus, err := a.menuService.GetMenuList(params)
	if err != nil {
		logger.Error("获取菜单列表失败: %v", err)
		c.JSON(http.StatusInternalServerError, model.Response{
			Code: 500,
			Msg:  "获取菜单列表失败: " + err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, model.Response{
		Code: 200,
		Msg:  "获取成功",
		Data: menus,
	})
}

// GetMenuTree 获取菜单树
// @Summary 获取菜单树
// @Description 获取树形菜单
// @Tags 菜单管理
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Success 200 {object} model.Response "成功"
// @Router /api/menus/tree [get]
func (a *MenuAPI) GetMenuTree(c *gin.Context) {
	tree, err := a.menuService.GetMenuTree()
	if err != nil {
		logger.Error("获取菜单树失败: %v", err)
		c.JSON(http.StatusInternalServerError, model.Response{
			Code: 500,
			Msg:  "获取菜单树失败: " + err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, model.Response{
		Code: 200,
		Msg:  "获取成功",
		Data: tree,
	})
}

// GetMenuByID 获取菜单详情
// @Summary 获取菜单详情
// @Description 获取菜单详情
// @Tags 菜单管理
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param id path int true "菜单ID"
// @Success 200 {object} model.Response "成功"
// @Router /api/menus/{id} [get]
func (a *MenuAPI) GetMenuByID(c *gin.Context) {
	idStr := c.Param("id")
	id, err := strconv.ParseUint(idStr, 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, model.Response{
			Code: 400,
			Msg:  "无效的菜单ID",
		})
		return
	}

	menu, err := a.menuService.GetMenuByID(uint(id))
	if err != nil {
		logger.Error("获取菜单详情失败: %v", err)
		c.JSON(http.StatusInternalServerError, model.Response{
			Code: 500,
			Msg:  "获取菜单详情失败: " + err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, model.Response{
		Code: 200,
		Msg:  "获取成功",
		Data: menu,
	})
}

// CreateMenu 创建菜单
// @Summary 创建菜单
// @Description 创建新菜单
// @Tags 菜单管理
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param data body model.CreateMenuRequest true "菜单信息"
// @Success 200 {object} model.Response "成功"
// @Router /api/menus [post]
func (a *MenuAPI) CreateMenu(c *gin.Context) {
	var req model.CreateMenuRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, model.Response{
			Code: 400,
			Msg:  "请求参数错误: " + err.Error(),
		})
		return
	}

	menu, err := a.menuService.CreateMenu(&req)
	if err != nil {
		logger.Error("创建菜单失败: %v", err)
		c.JSON(http.StatusInternalServerError, model.Response{
			Code: 500,
			Msg:  "创建菜单失败: " + err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, model.Response{
		Code: 200,
		Msg:  "创建成功",
		Data: menu,
	})
}

// UpdateMenu 更新菜单
// @Summary 更新菜单
// @Description 更新菜单信息
// @Tags 菜单管理
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param id path int true "菜单ID"
// @Param data body model.UpdateMenuRequest true "菜单信息"
// @Success 200 {object} model.Response "成功"
// @Router /api/menus/{id} [put]
func (a *MenuAPI) UpdateMenu(c *gin.Context) {
	idStr := c.Param("id")
	id, err := strconv.ParseUint(idStr, 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, model.Response{
			Code: 400,
			Msg:  "无效的菜单ID",
		})
		return
	}

	var req model.UpdateMenuRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, model.Response{
			Code: 400,
			Msg:  "请求参数错误: " + err.Error(),
		})
		return
	}

	menu, err := a.menuService.UpdateMenu(uint(id), &req)
	if err != nil {
		logger.Error("更新菜单失败: %v", err)
		c.JSON(http.StatusInternalServerError, model.Response{
			Code: 500,
			Msg:  "更新菜单失败: " + err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, model.Response{
		Code: 200,
		Msg:  "更新成功",
		Data: menu,
	})
}

// DeleteMenu 删除菜单
// @Summary 删除菜单
// @Description 删除菜单
// @Tags 菜单管理
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param id path int true "菜单ID"
// @Success 200 {object} model.Response "成功"
// @Router /api/menus/{id} [delete]
func (a *MenuAPI) DeleteMenu(c *gin.Context) {
	idStr := c.Param("id")
	id, err := strconv.ParseUint(idStr, 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, model.Response{
			Code: 400,
			Msg:  "无效的菜单ID",
		})
		return
	}

	err = a.menuService.DeleteMenu(uint(id))
	if err != nil {
		logger.Error("删除菜单失败: %v", err)
		c.JSON(http.StatusInternalServerError, model.Response{
			Code: 500,
			Msg:  "删除菜单失败: " + err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, model.Response{
		Code: 200,
		Msg:  "删除成功",
	})
}

// GetUserMenus 获取用户菜单
// @Summary 获取用户菜单
// @Description 获取当前用户的菜单树
// @Tags 菜单管理
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Success 200 {object} model.Response "成功"
// @Router /api/menus/user [get]
func (a *MenuAPI) GetUserMenus(c *gin.Context) {
	userID, exists := c.Get("userID")
	if !exists {
		c.JSON(http.StatusUnauthorized, model.Response{
			Code: 401,
			Msg:  "未授权",
		})
		return
	}

	menuTree, err := a.menuService.GetUserMenuTree(userID.(uint))
	if err != nil {
		logger.Error("获取用户菜单失败: %v", err)
		c.JSON(http.StatusInternalServerError, model.Response{
			Code: 500,
			Msg:  "获取用户菜单失败: " + err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, model.Response{
		Code: 200,
		Msg:  "获取成功",
		Data: menuTree,
	})
}
